package com.nantian.ecm.docmatcher.doc;

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.apache.poi.POIXMLDocument;
import org.apache.poi.POIXMLTextExtractor;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.hwpf.model.ListTables;
import org.apache.poi.hwpf.usermodel.CharacterRun;
import org.apache.poi.hwpf.usermodel.Paragraph;
import org.apache.poi.hwpf.usermodel.Table;
import org.apache.poi.hwpf.usermodel.TableCell;
import org.apache.poi.hwpf.usermodel.TableIterator;
import org.apache.poi.hwpf.usermodel.TableRow;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.xmlbeans.XmlException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.nantian.ecm.docmatcher.doc.exception.FileSuffixException;

/**
 * 基于POI的Word文档Reader
 * 
 * @author ldd
 *
 */
public class POIDocReader implements IDocReader {
	public final static Logger logger = LoggerFactory.getLogger(POIDocReader.class);

	/**
	 * Word文档
	 */
	private File docfile;

	public File getDocfile() {
		return docfile;
	}

	public void setDocfile(File docfile) {
		this.docfile = docfile;
	}

	@Override
	public List<String> getOutlines() {
		List<String> outLines = null;
		// doc
		if (docfile.getName().toLowerCase().endsWith(SUFFIX_DOC)) {
			try {
				WordExtractor we = this.read(docfile);
				HWPFDocument doc = new HWPFDocument(new FileInputStream(docfile));

				logger.debug(doc.getRange().text());
				// System.out.println(we.getText());
			} catch (IOException e) {
				logger.error("无效的文件,文件名={}", docfile.getName(), e);
			}

		} else {
			try {
				XWPFWordExtractor we = this.readX(docfile);

				XWPFDocument doc = new XWPFDocument(new FileInputStream(docfile));

				for (XWPFTable t : doc.getTables()) {
					for (XWPFTableRow r : t.getRows()) {
						for (XWPFTableCell c : r.getTableCells()) {
							logger.debug(c.getText());
						}
					}
				}
				// System.out.println(we.getText());
			} catch (IOException e) {
				logger.error("无效的文件,文件名={}", docfile.getName(), e);
			} catch (XmlException e) {
				logger.error("无效的文件格式,文件名={}", docfile.getName(), e);
			} catch (OpenXML4JException e) {
				logger.error("无效的文件格式,文件名={}", docfile.getName(), e);
			}
		}
		return outLines;
	}

	public static POIDocReader getInstance(String docFile) throws FileNotFoundException, FileSuffixException {
		POIDocReader reader = new POIDocReader();
		File docf = new File(docFile);
		if (!docf.exists()) {
			throw new FileNotFoundException(docFile);
		} else {
			if (docf.getName().toLowerCase().endsWith(SUFFIX_DOC)
					|| docf.getName().toLowerCase().endsWith(SUFFIX_DOCX)) {
				reader.setDocfile(new File(docFile));
				return reader;
			} else {
				throw new FileSuffixException("doc or docx", "unknown");
			}
		}
	}

	private WordExtractor read(File docFile) throws IOException {
		InputStream fis = new FileInputStream(docFile);
		WordExtractor ex = new WordExtractor(fis);
		return ex;
	}

	public XWPFWordExtractor readX(File docxFile) throws IOException, XmlException, OpenXML4JException {
		OPCPackage opcPackage = POIXMLDocument.openPackage(docxFile.getAbsolutePath());
		XWPFWordExtractor ex = new XWPFWordExtractor(opcPackage);
		return ex;
	}

	@Override
	public boolean matchRegx(String regxStr) {
		String docStr = getText();
		if (docStr != null) {
			return docStr.matches(regxStr);
		} else {
			return false;
		}
	}

	@Override
	public String getText() {
		String docStr = null;
		// doc
		if (docfile.getName().toLowerCase().endsWith(SUFFIX_DOC)) {
			try {
				WordExtractor we = this.read(docfile);
				HWPFDocument doc = new HWPFDocument(new FileInputStream(docfile));
				for (int i = 0; i < doc.getRange().numParagraphs(); i++) {
					Paragraph p = doc.getRange().getParagraph(i);
					// logger.info(p.text());
				}
				for (int i = 0; i < doc.getRange().numCharacterRuns(); i++) {
					CharacterRun cr = doc.getRange().getCharacterRun(i);
					logger.info(cr.text());
				}

				TableIterator tableIter = new TableIterator(doc.getRange());
				Table table;
				TableRow row;
				TableCell cell;
				while (tableIter.hasNext()) {
					table = tableIter.next();
					int rowNum = table.numRows();
					for (int j = 0; j < rowNum; j++) {
						row = table.getRow(j);
						int cellNum = row.numCells();
						for (int k = 0; k < cellNum; k++) {
							cell = row.getCell(k);
							// 输出单元格的文本
							logger.info("row={},cell={},text={}",j,k,cell.text().trim());
						}
					}
				}
				
				docStr=doc.getRange().text();
			} catch (IOException e) {
				logger.error("无效的文件,文件名={}", docfile.getName(), e);
			}

		} else {
			try {
				XWPFWordExtractor we = this.readX(docfile);
				docStr = we.getText();
			} catch (IOException e) {
				logger.error("无效的文件,文件名={}", docfile.getName(), e);
			} catch (XmlException e) {
				logger.error("无效的文件格式,文件名={}", docfile.getName(), e);
			} catch (OpenXML4JException e) {
				logger.error("无效的文件格式,文件名={}", docfile.getName(), e);
			}
		}
		return docStr;
	}

}
